package com.acdc.utils;

import java.security.SecureRandom;
import java.util.UUID;
import java.util.Base64;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * Token生成器工具类
 * 提供多种token生成方式，包括UUID、随机字符串、时间戳等
 * 
 * @author ACDC Platform
 * @version 1.0.0
 * @since 2024-01-01
 */
public class TokenGenerator {
    
    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static final String NUMERIC = "0123456789";
    private static final String ALPHA_NUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
    
    /**
     * 生成UUID格式的token
     * 
     * @return UUID字符串
     */
    public static String generateUUID() {
        return UUID.randomUUID().toString();
    }
    
    /**
     * 生成不带连字符的UUID格式token
     * 
     * @return 32位UUID字符串
     */
    public static String generateUUIDWithoutHyphens() {
        return UUID.randomUUID().toString().replace("-", "");
    }
    
    /**
     * 生成指定长度的随机字符串token
     * 
     * @param length token长度
     * @return 随机字符串
     */
    public static String generateRandomString(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("长度必须大于0");
        }
        
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(ALPHABET.charAt(SECURE_RANDOM.nextInt(ALPHABET.length())));
        }
        return sb.toString();
    }
    
    /**
     * 生成指定长度的数字token
     * 
     * @param length token长度
     * @return 数字字符串
     */
    public static String generateNumericToken(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("长度必须大于0");
        }
        
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(NUMERIC.charAt(SECURE_RANDOM.nextInt(NUMERIC.length())));
        }
        return sb.toString();
    }
    
    /**
     * 生成指定长度的字母数字混合token
     * 
     * @param length token长度
     * @return 字母数字混合字符串
     */
    public static String generateAlphaNumericToken(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("长度必须大于0");
        }
        
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(ALPHA_NUMERIC.charAt(SECURE_RANDOM.nextInt(ALPHA_NUMERIC.length())));
        }
        return sb.toString();
    }
    
    /**
     * 生成基于时间戳的token
     * 
     * @return 时间戳token
     */
    public static String generateTimestampToken() {
        return String.valueOf(System.currentTimeMillis());
    }
    
    /**
     * 生成格式化的时间token
     * 
     * @param pattern 时间格式模式
     * @return 格式化的时间字符串
     */
    public static String generateFormattedTimeToken(String pattern) {
        if (pattern == null || pattern.trim().isEmpty()) {
            pattern = "yyyyMMddHHmmss";
        }
        
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return now.format(formatter);
    }
    
    /**
     * 生成带时间戳的随机token
     * 
     * @param randomLength 随机部分长度
     * @return 时间戳+随机字符串
     */
    public static String generateTimestampRandomToken(int randomLength) {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String random = generateRandomString(randomLength);
        return timestamp + random;
    }
    
    /**
     * 生成Base64编码的token
     * 
     * @param length 原始随机字符串长度
     * @return Base64编码的token
     */
    public static String generateBase64Token(int length) {
        String randomString = generateRandomString(length);
        return Base64.getEncoder().encodeToString(randomString.getBytes(StandardCharsets.UTF_8));
    }
    
    /**
     * 生成URL安全的Base64编码token
     * 
     * @param length 原始随机字符串长度
     * @return URL安全的Base64编码token
     */
    public static String generateUrlSafeBase64Token(int length) {
        String randomString = generateRandomString(length);
        return Base64.getUrlEncoder().encodeToString(randomString.getBytes(StandardCharsets.UTF_8));
    }
    
    /**
     * 生成MD5哈希token
     * 
     * @param input 输入字符串
     * @return MD5哈希值
     */
    public static String generateMD5Token(String input) {
        if (input == null || input.trim().isEmpty()) {
            input = generateRandomString(16);
        }
        
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法不可用", e);
        }
    }
    
    /**
     * 生成SHA256哈希token
     * 
     * @param input 输入字符串
     * @return SHA256哈希值
     */
    public static String generateSHA256Token(String input) {
        if (input == null || input.trim().isEmpty()) {
            input = generateRandomString(16);
        }
        
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256算法不可用", e);
        }
    }
    
    /**
     * 生成自定义前缀的token
     * 
     * @param prefix 前缀
     * @param length 随机部分长度
     * @return 带前缀的token
     */
    public static String generatePrefixedToken(String prefix, int length) {
        if (prefix == null) {
            prefix = "";
        }
        String random = generateRandomString(length);
        return prefix + random;
    }
    
    /**
     * 生成带分隔符的组合token
     * 
     * @param parts 各部分内容
     * @param separator 分隔符
     * @return 组合后的token
     */
    public static String generateCombinedToken(String[] parts, String separator) {
        if (parts == null || parts.length == 0) {
            return generateRandomString(16);
        }
        
        if (separator == null) {
            separator = "_";
        }
        
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < parts.length; i++) {
            if (i > 0) {
                sb.append(separator);
            }
            sb.append(parts[i] != null ? parts[i] : "");
        }
        return sb.toString();
    }
    
    /**
     * 生成设备相关的token
     * 
     * @param deviceId 设备ID
     * @param randomLength 随机部分长度
     * @return 设备相关token
     */
    public static String generateDeviceToken(String deviceId, int randomLength) {
        if (deviceId == null || deviceId.trim().isEmpty()) {
            deviceId = "DEV";
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        String random = generateRandomString(randomLength);
        return deviceId + "_" + timestamp + "_" + random;
    }
    
    /**
     * 生成会话token
     * 
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @return 会话token
     */
    public static String generateSessionToken(String userId, String sessionId) {
        if (userId == null || userId.trim().isEmpty()) {
            userId = "USER";
        }
        if (sessionId == null || sessionId.trim().isEmpty()) {
            sessionId = generateUUIDWithoutHyphens();
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        return userId + "_" + sessionId + "_" + timestamp;
    }
    
    /**
     * 验证token格式（基本验证）
     * 
     * @param token 待验证的token
     * @return 是否有效
     */
    public static boolean isValidToken(String token) {
        return token != null && !token.trim().isEmpty() && token.length() >= 8;
    }
    
    /**
     * 生成默认token（推荐用于一般用途）
     * 
     * @return 默认格式的token
     */
    public static String generateDefaultToken() {
        return generateTimestampRandomToken(16);
    }
}
